<?php
// +----------------------------------------------------------------------
// | @filename ImageUploadHandler.php
// +----------------------------------------------------------------------
// | @author 落花轻舞问君愁 <mwcx1990@qq.com>
// +----------------------------------------------------------------------
// | @datetime 2020-08-10 17:50
// +----------------------------------------------------------------------
// | @Description
// +----------------------------------------------------------------------

namespace Addons\Backend\Handlers;

use Illuminate\Support\Facades\Storage;
use  Illuminate\Support\Str;

class ImageUploadHandler
{
    /**
     * @param $file
     * @param $folder
     * @param $subFolder
     * @param bool $rename
     * @param false $isBase64
     * @param float|int $maxSize 最大上传大小 单位Byte（字节） 1M = 1 * 1024 * 1024  500KB = 50 * 1024 ，默认2M
     * @param string[] $allowedMimeType
     * @param string $filePrefix
     * @param bool $createDir
     * @return array
     */
    public function save($file, $folder, $rename = true, $isBase64 = false, $subFolder = '', $maxSize = 2 * 1024 * 1024, $allowedMimeType = ['image/png', 'image/bmp', 'image/jpeg', 'image/jpg'], $filePrefix = '', $createDir = true)
    {

        $maxSizeFormat = ($maxSize / 1024 < 1024) ? ($maxSize / 1024) . 'KB' : ($maxSize / 1024 / 1024) . 'M';
        if ($isBase64) {

            preg_match('/^(data:\s*image\/(\w+);base64,)/', $file, $res);
            if (empty($res)) {
                return [
                    'code' => 1,
                    'message' => '上传的图片异常,请重新选择图片'
                ];
            }
            $file = base64_decode(str_replace($res[1], '', $file));

            $fileSize = strlen($file); //获取大小向上取整
            if ($fileSize > $maxSize) {
                return [
                    'code' => 1,
                    'message' => "上传的图片不能超过{$maxSizeFormat},请重新选择图片"
                ];
            }

            $mimeType = explode(':', explode(';', $res[1])[0])[1];
            // 获取文件的后缀名，因图片从剪贴板里黏贴时后缀名为空，所以此处确保后缀一直存在
            $extension = $res[2] ?: 'png';
        } else {
            $mimeType = $file->getMimeType();
            // 获取文件的后缀名，因图片从剪贴板里黏贴时后缀名为空，所以此处确保后缀一直存在
            $extension = strtolower($file->getClientOriginalExtension()) ?: 'png';

            if ($file->getSize() > $maxSize) {
                return [
                    'code' => 1,
                    'message' => "上传的图片不能超过{$maxSizeFormat},请重新选择图片"
                ];
            }
//            if($file->get > $maxSize){
//                return [
//                    'code' => 1,
//                    'message' => '上传的图片不能超过2M,请重新选择图片'
//                ];
//            }
        }

        // 如果上传的不是图片将终止操作
        if (!in_array($mimeType, $allowedMimeType)) {
            return [
                'code' => 1,
                'message' => '上传的图片格式不正确'
            ];
        }

        // 构建存储的文件夹规则，值如：uploads/images/avatars/201709/21/
        // 文件夹切割能让查找效率更高。
        if ($createDir) {
            $folderName = "uploads/images/$folder/" . date("Ym/d");
        } else {
            $folderName = "uploads/images/$folder";
        }

        if ($subFolder) {
            $folderName .= '/' . $subFolder;
        }

        // 是否重命名文件
        if ($rename || $isBase64) { //base64的图片二进制必须重命名，因为无法获取到文件名
            $filename = time() . '_' . Str::random(10) . '.' . $extension;
        } else {
            $filename = $file->getClientOriginalName();
        }

        // 拼接文件名，加前缀是为了增加辨析度，前缀可以是相关数据模型的 ID
        // 值如：1_1493521050_7BVc9v9ujP.png
        if (!empty($filePrefix)) {
            $filename = $filePrefix . $filename;
        }

        // 将图片移动到我们的目标存储路径中
        if ($isBase64) {
             $res = Storage::disk('public')->put("$folderName/$filename", $file);
        } else {
             $res = $file->storeAs($folderName, $filename, 'public');
        }

        if (!$res) {
            return [
                'code' => 1,
                'message' => '上传图片异常,请稍后再试'
            ];
        }

        return [
            'code' => 0,
            'message' => '上传图片成功',
            'data' => [
                "url" => url("/storage/$folderName/$filename"),
                "path" => "/storage/$folderName/$filename"
            ]
        ];
    }

}
